<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="../css/common.css" media="all" />
<link rel="stylesheet" type="text/css" href="../css/article.css" media="all" />
</head>
<body>
<div id="w3h_body">
  <div class="body_content">
    <!-- toc begin -->
    <h1 class="title">HO8001: 各浏览器下使用 OBJECT 元素和 EMBED 元素嵌入 Flash 存在差异</h1>
    <ul class="toc">
      <li><a href="#standard_reference">标准参考</a> <span>•</span></li>
      <li><a href="#description">问题描述</a> <span>•</span></li>
      <li><a href="#influence">造成的影响</a> <span>•</span></li>
      <li><a href="#impacted_browsers">受影响的浏览器</a> <span>•</span></li>
      <li><a href="#analysis_of_issues">问题分析</a> <span>•</span></li>
      <li><a href="#solutions">解决方案</a> <span>•</span></li>
      <li><a href="#see_also">参见</a></li>
    </ul>
    <!-- toc end -->
    <div id="w3h_content">
      <!-- content begin -->
      <address class="author">作者：陆远</address>
      <h2 id="standard_reference">标准参考</h2>
      <p>OBJECT 元素定义了一个嵌入的对象。其引入的初衷是取代 IMG 和 APPLET 元素。不过由于安全等各方面原因以及缺乏浏览器支持，这一初衷并未实现。浏览器的对象支持依赖于对象类型。然而，即便是相同的对象类型，各主流浏览器也都使用了不同的代码来加载。
      classid 属性用于指定对象实现的 URI 地址。它可能用来替代或者配合 data 属性，这由引入的对象决定。<br />
      codebase 属性指定了一个为 classid、data、archive 属性的相对 URI 提供基本路径。缺省情况下，这个值为当前文档的基本 URI。<br />
      type 属性定义被定义在 data 属性中指定的文件中出现的数据的 MIME 类型。</p>
      <p>关于 OBJECT 元素及其属性的详细信息，请参考 HTML4.01 规范 <a href="http://www.w3.org/TR/html401/struct/objects.html#h-13.3">13.3 Generic inclusion: the OBJECT element</a> 中的内容。</p>

      <h2 id="description">问题描述</h2>
      <p>通常情况下，IE 系列浏览器通过 ActiveX 插件使用 OBJECT 元素引入 Flash，而其他浏览器则是通过相应的 NPAPI 插件使用 EMBED 元素。这造成了各浏览器中插入 Flash 的方式的差异。</p>

      <h2 id="influence">造成的影响</h2>
      <p>若仅仅使用 OBJECT 元素设置了 classid 属性引入 Flash，则可能造成在某些浏览器中 Flash 无法被引入。而若嵌套的 OBJECT 和 EMBED 元素参数不统一，也可能造成引入的 Flash 在各浏览器中出现差异。</p>

      <h2 id="impacted_browsers">受影响的浏览器</h2>
      <table class="list">
        <tr>
          <th>所有浏览器</th>
          <td>&nbsp;</td>
        </tr>
      </table>

      <h2 id="analysis_of_issues">问题分析</h2>
      <p>对于 HTML4.01 规范中的 OBJECT 元素，IE 对 classid 属性有自己的解释方式：类标识符（class identifier）。格式形如：clsid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX。由 ActiveX 组件注册在 Windows 的系统注册表中。<br />
      codebase 属性则为该类标识符所对应的 ActiveX 插件的 URI 地址。一般是一个 .cab 安装包。（更多请参考 MSDN：<a href="http://msdn.microsoft.com/en-us/library/ms533559(v=VS.85).aspx">CLASSID Attribute | classid Property</a> 及 <a href="http://msdn.microsoft.com/en-us/library/aa378911(VS.85).aspx">Class Identifier</a> 中的内容。）</p>
      <p>EMBED 元素则是由 NetScape Navigator 2 引入，用于在 HTML 文档中插入符合网景插件应用程序编程接口（NPAPI）规范的插件。NPAPI 插件是跨平台的，并可以在所有实现了此接口规范的浏览器中使用。目前的主流浏览器中 IE 系列以外的浏览器均支持 NPAPI 插件。<br />
      事实上 IE3.0 就支持 NPAPI，但是在 IE5.5 SP2 后微软出于安全考虑停止了对 NPAPI 的支持，转而推荐用户使用其 ActiveX 技术作为替代。（更多请参考 MSDN：<a href="http://support.microsoft.com/kb/303401">Netscape 式的插件在升级 Internet Explorer 后不工作</a>）<br />
      EMBED 元素拥有一个名为 pluginspage 的属性，其值为 NPAPI 插件的 URL，与 IE 中 OBJECT 元素的 codebase 属性类似，它告诉了浏览器插件的下载地址。</p>
      <p>EMBED 元素不属于 HTML4.01 规范中的元素，HTML 文档中直接使用 EMBED 元素可能无法通过 W3C 校验。不过 EMBED 元素目前已经被添加到 HTML5 草案中。（参加 HTML5 草案：<a href="http://www.w3.org/TR/html5/the-iframe-element.html#the-embed-element">4.8.3 The embed element</a>）</p>
      <p>至此若需要在 HTML 文档中引入一个已安装的通用的插件，如 Flash，则在 IE 中使用 OBJECT 元素，非 IE 中则使用 EMBED 元素。此外 IE 中也支持 EMBED 元素引入设置了正确 MIME 的插件。</p>
      <br />
      <p>通常，我们会使用类似如下结构的代码引入 Flash：<em>flash.html</em>（SWF 文件来自 Adobe 网站的 Flash 范例）</p>
      <pre>&lt;object width="200" height="200" <strong>classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#4,0,0,0"</strong>&gt;
  &lt;param name="src" value="<em>clock.swf</em>" /&gt;
  &lt;param name="quality" value="high" /&gt;
  &lt;embed src="<em>clock.swf</em>" type="application/x-shockwave-flash" width="200" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;
&lt;/object&gt;</pre>
      <p>各浏览器中的效果均为：<br />
      <img src="../../tests/HO8001/flash_clock.gif" alt="" /></p>
      <p>将 EMBED 元素嵌套在 OBJECT 元素中，在 IE 中会优先使用 OBJECT 元素而忽略 EMBED 元素，在其他浏览器中则优先使用 EMBED 元素而忽略 OBJECT 元素。这样做虽然可以保证在所有浏览器中均能正确加载 Flash，但若 OBJECT 元素与 EMBED 元素的参数设定不统一，则很有可能造成 Flash 在各浏览器中显示效果不一致，甚至是无法正常加载。</p>
      <p>关于如何正确地在 HTML 文档中引入 Flash，请参考 Adobe 官方知识库文档：<a href="http://kb2.adobe.com/cps/415/tn_4150.html">OBJECT and EMBED syntax | Flash</a> 与 <a href="http://kb2.adobe.com/cps/127/tn_12701.html">Flash OBJECT and EMBED tag attributes</a>中的内容。</p>
      <br />
      <p>下面将分析仅使用一种元素的引入 Flash 的情况下在所有主流浏览器中是否达到一致的效果。（假设浏览器均已正确安装 Flash 所需插件）</p>
      <h3>1. 使用 OBJECT 元素 classid 属性以及 PARAM 元素：<em>flash_object_classid.html</em></h3>
      <pre>&lt;div style="border:5px solid black; padding:5px; float:left;"&gt;
  &lt;object width="200" height="200" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#4,0,0,0"&gt;
    &lt;param name="src" value="clock.swf" /&gt;
    &lt;param name="quality" value="high" /&gt;
  &lt;/object&gt;
&lt;/div&gt;</pre>
      <p>这段代码在各浏览器中运行效果如下：</p>
      <table class="compare">
        <tr>
          <th>IE6 IE7 IE8 Chrome<sup>1</sup> Safari</th>
          <th>Firefox Opera</th>
        </tr>
        <tr>
          <td><img src="../../tests/HO8001/object_classid_1.gif" alt="IE6 IE7 IE8 Chrome Safari" /></td>
          <td><img src="../../tests/HO8001/object_classid_2.gif" alt="Firefox Opera" /></td>
        </tr>
      </table>
      <p>Firefox 和 Opera 由于不支持 ActiveX 技术所有无法通过 OBJECT 元素及 classid 属性引入 Flash，则此时 OBJECT 元素宽度和高度均为 0。<br />
      然而 Chrome 和 Safari 却正确的加载了 Flash 文件，这是由于 WebKit 内核对 ActiveX 提供了有限的支持，对于比较通用的 ActiveX 插件（如 Flash, Media Player, Director, QuickTime, RealAudio），浏览器会将它们的在 Windows 系统中的 classid 与其对应的 Mime-Type 相关联，所以可以和 IE 一样仅仅通过 OBJECT 元素的 classid 属性引入这些插件。</p>
      <p class="comment">【注】：Chrome 后续版本对此处实现做了修正，已无法通过 classid 来加载 Flash 文件。</p>
      <br />
      <h3>2. 使用 OBJECT 元素 type、data 属性：<em>flash_object_type.html</em></h3>
      <pre>&lt;div style="border:5px solid black; padding:5px; float:left;"&gt;
  &lt;object width="200" height="200" type="application/x-shockwave-flash" data="<em>clock.swf</em>"&gt;
  &lt;/object&gt;
&lt;/div&gt;</pre>
      <p>这段代码在各浏览器中运行效果如下：</p>
      <table class="compare">
        <tr>
          <th>IE6 IE7 IE8</th>
          <th>Firefox Chrome Safari Opera</th>
        </tr>
        <tr>
          <td><img src="../../tests/HO8001/object_type_1.gif" alt="IE6 IE7 IE8" /></td>
          <td><img src="../../tests/HO8001/object_classid_1.gif" alt="Firefox Chrome Safari Opera" /></td>
        </tr>
      </table>
      <p>IE 对 OBJECT 元素的 data 属性设置 Flash 文件 URL 无任何效果。这种方式可以用于非 IE 浏览器。</p>
      <br />
      <h3>3. 使用 OBJECT 元素 type、data 属性以及 PARAM 元素：<em>flash_object_all.html</em></h3>
      <pre>&lt;div style="border:5px solid black; padding:5px; float:left;"&gt;
  &lt;object width="200" height="200" type="application/x-shockwave-flash" data="<em>clock.swf</em>"&gt;
    &lt;param name="src" value="<em>clock.swf</em>" /&gt;
    &lt;param name="quality" value="high" /&gt;
  &lt;/object&gt;
&lt;/div&gt;</pre>
      <p>这种方式仍然仅使用 W3C 规范中标准的 OBJECT 元素，结合了上两个测试样例，使得所有浏览器均可以正常的载入 Flash 文件。</p>
      <br />
      <h3>4. 使用 EMBED 元素：<em>flash_embed.html</em></h3>
      <pre>&lt;div style="border:5px solid black; padding:5px; float:left;"&gt;
  &lt;embed src=&quot;<em>clock.swf</em>&quot; type="application/x-shockwave-flash" width="200" height="200" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;
&lt;/div&gt;</pre>
      <p>直接使用 EMBED 元素，所有浏览器均支持。</p>

      <h2 id="solutions">解决方案</h2>
      <ol>
        <li>若不考虑 W3C 校验，可统一使用 EMBED 元素嵌入 Flash，这样可以避免因参数不统一导致的兼容性问题。</li>
        <li>若需要考虑 W3C 校验（<a href="http://validator.w3.org/"><img src="../../tests/HO8001/w3c.png" style="height:14px;" alt="swfobject" /> Markup Validation Service</a>），则可使用第三种单独使用 OBJECT 与 PARAM 元素的方式。</li>
        <li>若必须使用 OBJECT 嵌套 EMBED 元素这种混合方式，则要保证 Flash 文件 URL、为 Flash 传递的参数、宽度、高度、wmode 等参数保持统一。</li>
        <li>可以使用开源的 SWFObject 引入 Flash。（请参见：<a href="http://code.google.com/p/swfobject/"><img src="../../tests/HO8001/swfobject_logo.gif" style="height:14px;" alt="swfobject" /></a>）</li>
      </ol>

      <h2 id="see_also">参见</h2>
      <h3>知识库</h3>
      <ul class="see_also">
        <li><a href="#">...</a></li>
      </ul>

      <h3>相关问题</h3>
      <ul class="see_also">
        <li><a href="BT9024">BT9024：IE 中可以使用 classid 与 codebase 属性结合完成下载、安装和使用 ActiveX 插件</a></li>
        <li><a href="HO9006">HO9006：Firefox Opera 不支持通过为 OBJECT 元素设置 classid 引入 Windows 下的 Media Player 或 Flash 插件</a></li>
      </ul>

      <div class="appendix">
        <h2>测试环境</h2>
        <table class="list">
          <tr>
            <th>操作系统版本:</th>
            <td>Windows 7 Ultimate build 7600</td>
          </tr>
          <tr>
            <th>浏览器版本:</th>
            <td>
              IE6<br />
              IE7<br />
              IE8<br />
              Firefox 3.6.8<br />
              Chrome 6.0.472.11 dev<br />
              Safari 5.0.1<br />
              Opera 10.60
            </td>
          </tr>
          <tr>
            <th>测试页面:</th>
            <td><a href="../../tests/HO8001/flash.html">flash.html</a><br />
            <a href="../../tests/HO8001/flash_object_classid.html">flash_object_classid.html</a><br />
            <a href="../../tests/HO8001/flash_object_type.html">flash_object_type.html</a><br />
            <a href="../../tests/HO8001/flash_object_all.html">flash_object_all.html</a><br />
            <a href="../../tests/HO8001/flash_embed.html">flash_embed.html</a></td>
          </tr>
          <tr>
            <th>本文更新时间:</th>
            <td>2010-07-31</td>
          </tr>
        </table>

        <h2>关键字</h2>  
        <!-- keywords begin -->
        <p>Flash EMBED OBJECT type param classid NPAPI ActiveX 插件</p>
        <!-- keywords end -->
      </div>
      <!-- content end -->
    </div>
  </div>
</div>
</body>
</html>
